/*
	Copyright 2008 Jay Elliott

	This file is part of libemath.

	libemath is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	libemath is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with libemath.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef __MATRIX_H_
#define __MATRIX_H_

#include <cmath>
#include <string>
#include <sstream>

#include "macros.h"
#include "cPoint3d.h"

namespace emath
{

class cMatrix
{
private:
	float mat[16];//the actual matrix

public:
	inline cMatrix(const float *matrix);
	inline cMatrix();
	inline cMatrix(const cMatrix &other);//copy constructor
	inline ~cMatrix();

	inline float& operator()(unsigned col, unsigned row);//index into the matrix, column major style.
	inline bool operator=(const cMatrix &other);
	cMatrix operator*(cMatrix right);
	cMatrix transpose(void);
	inline float& operator[](unsigned index);

	void LoadIdentity(void);

	friend cPoint3d operator*(cPoint3d point, cMatrix mat);

	inline void ToFloat(float ret[16]);

	bool operator==(const cMatrix& other) const;
};

cPoint3d operator*(cPoint3d point, cMatrix mat);







/*************************************
*
*
*	inline function definitions
*
*
***************************************/


cMatrix::cMatrix()
{
	LoadIdentity();
}

cMatrix::cMatrix(const float *matrix)
{
	for (unsigned i = 0; i < 16; i++)
		mat[i] = matrix[i];
}

cMatrix::cMatrix(const cMatrix& other)
{
	for (unsigned i = 0; i < 16; i++)
		mat[i] = other.mat[i];
}

cMatrix::~cMatrix()
{
}

float& cMatrix::operator()(unsigned col, unsigned row)
{
	return mat[index2d(4, row, col)];
}

void cMatrix::ToFloat(float ret[16])
{
	for (int i = 0; i < 16; i++)
		ret[i] = mat[i];
}

float& cMatrix::operator[](unsigned index)
{
	return mat[index];
}

bool cMatrix::operator=(const cMatrix &other)
{
	for (unsigned i = 0; i < 16; i++)
		mat[i] = other.mat[i];
}


}
#endif
